00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef _bus_table_hpp_
00028 #define _bus_table_hpp_
00029
00030 #define NUM_SLICES 10
00031
00032 #include <ga.h>
00033 #include <boost/unordered_map.hpp>
00034 #include "gridpack/parser/hash_distr.hpp"
00035 #include "gridpack/utilities/exception.hpp"
00036 #include "gridpack/utilities/string_utils.hpp"
00037
00038 namespace gridpack {
00039 namespace bus_table {
00040
00041 typedef struct {
00042 int order;
00043 char tag[3];
00044 } table_t;
00045
00046
00047
00048
00049 template <typename _network>
00050 class BusTable {
00051
00052 public:
00053 typedef _network NetworkType;
00054 typedef boost::shared_ptr<NetworkType> NetworkPtr;
00055
00056
00057
00058 BusTable(const boost::shared_ptr<_network> network)
00059 : p_network(network)
00060 {
00061 p_comm = p_network->communicator();
00062 p_has_data = false;
00063 }
00064
00065
00066 ~BusTable(void)
00067 {
00068 if (p_has_data) GA_Destroy(p_GA_data);
00069 }
00070
00071
00072 bool readTable(std::string &filename)
00073 {
00074 if (p_has_data) GA_Destroy(p_GA_data);
00075 int me = p_comm.rank();
00076 MPI_Comm mpi_comm = static_cast<MPI_Comm>(p_comm);
00077 p_GAgrp = p_comm.getGroup();
00078 int ifound = 1;
00079 int nval = 0;
00080 int nline = 0;
00081 gridpack::utility::StringUtils util;
00082 p_headers.clear();
00083 if (me == 0) {
00084
00085
00086 std::ifstream input;
00087 input.open(filename.c_str());
00088 if (!input.is_open()) {
00089 std::cout<<"File "<<filename<<" not found by readTable"<<std::endl;
00090 ifound = 0;
00091 } else {
00092 std::string line;
00093
00094 if (!std::getline(input,line).eof()) {
00095 util.trim(line);
00096 bool found = true;
00097 while (line[0] == '#') {
00098
00099
00100 line[0] = ' ';
00101 util.trim(line);
00102 p_headers.push_back(line);
00103 found = !std::getline(input,line).eof();
00104 }
00105 if (found) {
00106 util.trim(line);
00107 std::vector<std::string> split_line;
00108 boost::split(split_line,line,boost::algorithm::is_any_of(" "),
00109 boost::token_compress_on);
00110 nval = split_line.size() - 2;
00111 if (nval > 0) {
00112 nline = 1;
00113 while(!std::getline(input,line).eof()) {
00114 nline++;
00115 }
00116 } else {
00117 ifound = 0;
00118 }
00119 }
00120 } else {
00121 ifound = 0;
00122 }
00123 }
00124 input.close();
00125
00126
00127
00128
00129
00130 int irecv;
00131 MPI_Bcast(&ifound,1,MPI_INT,0,mpi_comm);
00132 if (ifound == 1) {
00133 MPI_Bcast(&nval,1,MPI_INT,0,mpi_comm);
00134 MPI_Bcast(&nline,1,MPI_INT,0,mpi_comm);
00135 } else {
00136 return false;
00137 }
00138 } else {
00139 MPI_Bcast(&ifound,1,MPI_INT,0,mpi_comm);
00140 if (ifound == 1) {
00141 MPI_Bcast(&nval,1,MPI_INT,0,mpi_comm);
00142 MPI_Bcast(&nline,1,MPI_INT,0,mpi_comm);
00143 } else {
00144 return false;
00145 }
00146 }
00147 p_nobjs = nline;
00148 p_nvals = nval;
00149
00150
00151
00152
00153 if (nval > 0 && nline > 0) {
00154
00155 int nheaders = 0;
00156 if (me == 0) {
00157 nheaders = p_headers.size();
00158 }
00159 MPI_Bcast(&nheaders,1,MPI_INT,0,mpi_comm);
00160 int *hsize;
00161 hsize = new int[nheaders];
00162 int i;
00163 if (me == 0) {
00164 for (i=0; i<nheaders; i++) {
00165 hsize[i] = p_headers[i].length();
00166 }
00167 }
00168 MPI_Bcast(hsize,nheaders,MPI_INT,0,mpi_comm);
00169 for (i=0; i<nheaders; i++) {
00170 char *str;
00171 str = new char[hsize[i]];
00172 int j;
00173 if (me == 0) {
00174 for (j=0; j<hsize[i]; j++) {
00175 str[j] = (p_headers[i])[j];
00176 }
00177 }
00178 MPI_Bcast(str,hsize[i],MPI_CHAR,0,mpi_comm);
00179 if (me != 0) {
00180 p_headers.push_back(str);
00181 }
00182 delete [] str;
00183 }
00184 delete [] hsize;
00185 gridpack::utility::StringUtils util;
00186
00187 p_GA_data = GA_Create_handle();
00188 int ndim = 1;
00189 int dims = nline*nval;
00190 GA_Set_data(p_GA_data,ndim,&dims,C_DBL);
00191 GA_Set_pgroup(p_GA_data,p_GAgrp);
00192 GA_Allocate(p_GA_data);
00193 std::vector<table_t> order;
00194 std::vector<int> bus_id;
00195 if (me == 0) {
00196 int i;
00197 int ncnt = 0;
00198 int lo, hi;
00199 lo = 0;
00200
00201 double *buf = new double[NUM_SLICES*nval];
00202 double *ptr = buf;
00203 std::ifstream input;
00204 input.open(filename.c_str());
00205 std::vector<std::string> split_line;
00206 std::string line;
00207 while(!std::getline(input,line).eof()) {
00208 while (line[0] == '#') {
00209
00210
00211 std::getline(input,line);
00212 }
00213 util.trim(line);
00214 boost::split(split_line,line,boost::algorithm::is_any_of(" "),
00215 boost::token_compress_on);
00216 table_t data;
00217 data.order = ncnt;
00218 std::string tag = split_line[1];
00219 std::string new_tag = util.clean2Char(tag);
00220 strncpy(data.tag,new_tag.c_str(),2);
00221 data.tag[2] = '\0';
00222 bus_id.push_back(atoi(split_line[0].c_str()));
00223 order.push_back(data);
00224 for (i=0; i<nval; i++) {
00225 ptr[i] = atof(split_line[i+2].c_str());
00226 }
00227 ptr += nval;
00228 ncnt++;
00229 if (ncnt%NUM_SLICES == 0) {
00230 hi = ncnt*nval-1;
00231 NGA_Put(p_GA_data,&lo,&hi,buf,&nval);
00232 ptr = buf;
00233 lo = ncnt*nval;
00234 }
00235 }
00236 if (ncnt != nline) {
00237 printf("Mismatch parsing data in table %s\n",filename.c_str());
00238 }
00239 if (ncnt%NUM_SLICES != 0) {
00240 hi = nline*nval-1;
00241 NGA_Put(p_GA_data,&lo,&hi,buf,&nval);
00242 }
00243 input.close();
00244 delete [] buf;
00245 }
00246
00247 p_comm.sync();
00248
00249
00250 gridpack::hash_distr::HashDistribution<NetworkType,table_t,table_t>
00251 *hash;
00252 hash = new gridpack::hash_distr::HashDistribution
00253 <NetworkType,table_t,table_t>(p_network);
00254 hash->distributeBusValues(bus_id,order);
00255 delete hash;
00256 p_local_idx.clear();
00257 p_tags.clear();
00258 p_order.clear();
00259 for (i=0; i<bus_id.size(); i++) {
00260 p_local_idx.push_back(bus_id[i]);
00261 std::string tmp(order[i].tag);
00262 std::string new_tag = util.clean2Char(tmp);
00263 p_tags.push_back(new_tag);
00264 p_order.push_back(order[i].order);
00265 }
00266 }
00267 p_has_data = true;
00268 return true;
00269 }
00270
00271
00272
00273
00274
00275 void getLocalIndices(std::vector<int> &indices) {
00276 indices.clear();
00277 int nval = p_local_idx.size();
00278 int i;
00279 for (i=0; i<nval; i++) {
00280 indices.push_back(p_local_idx[i]);
00281 }
00282 }
00283
00284
00285
00286
00287
00288 void getTags(std::vector<std::string> &tags) {
00289 tags.clear();
00290 int nval = p_tags.size();
00291 int i;
00292 for (i=0; i<nval; i++) {
00293 tags.push_back(p_tags[i]);
00294 }
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304 void getValues(int idx, std::vector<double> &values) {
00305 values.clear();
00306 if (idx < 0 || idx >= p_nvals) {
00307 printf("Requested data is out of range of bus table (%d not in [0,%d])\n",
00308 idx,p_nvals-1);
00309 }
00310
00311 int nsize = p_local_idx.size();
00312 std::vector<double> v(nsize);
00313 std::vector<int> array(nsize);
00314 std::vector<int*> subscript(nsize);
00315 int *ptr = &array[0];
00316 int i;
00317 for (i=0; i<nsize; i++) {
00318 array[i] = p_nvals*p_order[i] + idx;
00319 subscript[i] = ptr;
00320 ptr++;
00321 }
00322 NGA_Gather(p_GA_data, &v[0], &subscript[0], nsize);
00323 p_comm.sync();
00324 for (i=0; i<nsize; i++) {
00325 values.push_back(v[i]);
00326 }
00327 }
00328
00329 void getHeaders(std::vector<std::string> &headers) {
00330 headers.clear();
00331 int i;
00332 for (i=0; i<p_headers.size(); i++) {
00333 headers.push_back(p_headers[i]);
00334 }
00335 }
00336
00337
00338
00339
00340 int getNumColumns()
00341 {
00342 return p_nvals;
00343 }
00344 private:
00345
00346 NetworkPtr p_network;
00347
00348 gridpack::parallel::Communicator p_comm;
00349 int p_GA_data;
00350 bool p_has_data;
00351 int p_nvals;
00352 int p_nobjs;
00353
00354 std::vector<int> p_local_idx;
00355 std::vector<std::string> p_tags;
00356 std::vector<int> p_order;
00357 std::vector<std::string> p_headers;
00358
00359 int p_GAgrp;
00360 };
00361
00362
00363 }
00364 }
00365
00366 #endif
00367